<?php

namespace App\Http\Controllers\Admin\AirLine\Flight;

use App\Exceptions\AppException;
use App\Http\Controllers\Controller;
use App\Imports\CargoImport;
use App\Models\airline\base\BanModel;
use App\Models\airline\base\FlightModel as BaseFlightModel;
use App\Models\airline\base\RouteModel;
use App\Models\client\CommonPriceModel;
use App\Models\CustomerPreferenceModel;
use App\Models\DestinationRuleModel;
use App\Models\DictionaryModel;
use App\Models\finance\ReceivableGenericModel;
use App\Models\finance\ReceivableTemplate1Model;
use App\Models\FlightModel;
use App\Models\OrderModel;
use App\Models\OrderVolumeModel;
use App\Models\TakeOrderModel;
use App\Models\TakeOrderRecModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;

//配舱
class Cargo extends Controller
{
    //未配舱入仓单
    public function unfinished(Request $request) {
        $id = $request->input('flight_id', 0);
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 20);
        $customer_name = $request->input('customer_name', '');
        $customer_id = $request->input('customer_id', '');
        $goods_attr = $request->input('goods_attr', '');
        $clearance_mode = $request->input('clearance_mode', '');
        $customer_type_id = $request->input('customer_type_id', '');
        $is_clearance = $request->input('is_clearance', '');
        $pre_out_date_start = $request->input('pre_out_date_start', '');
        $pre_out_date_end = $request->input('pre_out_date_end', '');
        $destination = $request->input('des_country_id', '');
        $sn = $request->input('sn', '');

        $flight = FlightModel::find($id);
        if(!$flight) {
            return $this->success();
        }

        $query = OrderModel::query()
        ->where('cargo_status', OrderModel::CARGO_STATUS_NO)
            ->where('is_child', 0)
        ->withCount('split_order_addr');

        if($sn){
            $query->where('sn', $sn);
        }

        if($customer_name){
            $query->whereHas('customer', function ($query) use ($customer_name){
                if($customer_name){
                    $query->where('name', 'like', '%'.$customer_name.'%');
                }
            });
        }

        if($customer_id){
            $query->where('customer_id', $customer_id);
        }

        if($destination){
            $query->where('destination', $destination);
        }

        if($goods_attr){
            $query->where('goods_attr', $goods_attr);
        }

        if($clearance_mode){
            $query->where('clearance_mode', $clearance_mode);
        }

        if($is_clearance){
            $query->where('is_clearance', $is_clearance);
        }

        if($pre_out_date_start && $pre_out_date_end){
            $query->whereBetween('pre_out_date', [$pre_out_date_start, $pre_out_date_end]);
        }

        $total = $query->count('id');
        $items = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $list = $items->map(function($item) {
            $packages = $item->packages ?? '';
            $packages = DictionaryModel::whereIn('id', explode(',', $packages))
                ->pluck('name');

            if($item->children_nums > 0){
                $children = OrderModel::where('father_order_id', $item->id)->select('id', 'sn', 'big_pkgs', 'storage_weight')->get();
            }else{
                $children = [];
            }
            return [
                'id' => $item->id,
                'customer_name' => $item->customer->name ?? '',
                'sn' => $item->sn,
                'status_name' => OrderModel::STATUS_MAPS[$item->status] ?? '',
                'big_pkgs' => $item->big_pkgs,
                'pre_out_date' => $item->pre_out_date,
                'des_country_name' => $item->destination ?? '',
                'goods_attr_name' => OrderModel::GOODS_ATTR_MAPS[$item->goods_attr] ?? '',
                'clearance_mode' => OrderModel::CLEARANCE_MODE_MAPS[$item->clearance_mode] ?? '',
                'is_clearance' => $item->is_clearance,
                'storage_weight' => $item->storage_weight,
                'storage_volume' => round($item->storage_volume, 4),
                'pre_volume_weight' => round($item->bubble_weight, 2),
                'volume_ratio' => round($item->pre_weight != 0 ? ($item->pre_volume * 166.67) / $item->pre_weight : 0, 2),
                'packages_name' => $packages,
                'car_number' => $item->car_number,
                'children' => $children,
            ];
        });

        return $this->success(['list' => $list, 'total' => $total]);
    }

    //预配舱
    public function add_pre(Request $request) {
        $flight_id = $request->input('flight_id', 0);
        $ids = $request->input('ids', []);

        if(empty($ids)) {
            return $this->error('请选择入仓单');
        }

        $flight = FlightModel::find($flight_id);
        if(!$flight) {
            return $this->error('航班运力不存在');
        }

        $orders = OrderModel::withCount('split_order_addr')->whereIn('id', $ids)->get();
        if($orders->isEmpty()) {
            return $this->error('入仓单不存在');
        }

        $sum_volume = round($orders->sum('storage_volume'), 4);

        $sum_weight = round($orders->sum('storage_weight'), 2);


        if($orders->count() != count($ids)) {
            return $this->error('入仓单错误');
        }

        $destination = array_unique($orders->pluck('destination')->toArray());
        if(count($destination) != 1) {
            return $this->error('入仓单目的地不一致');
        }

        DB::beginTransaction();
        try {

            foreach ($orders as $order) {
                if($order->cargo_status == OrderModel::CARGO_STATUS_FILL || $order->cargo_status == OrderModel::CARGO_STATUS_NO_FILL) {
                    throw new AppException('入仓单已配舱');
                }

                $order->cargo_status = OrderModel::CARGO_STATUS_NO_FILL;
                $order->flight_id = $flight->id;
                $order->save();
            }

            $flight->surplus_volume -= $sum_volume;
            $flight->surplus_weight -= $sum_weight;
            $flight->save();

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
        return $this->success();

    }


    //添加配舱
    public function add(Request $request){
        $flight_id = $request->input('flight_id', 0);
        $ids = $request->input('ids', []);
        $take_order_no = $request->input('take_order_no', '');
        $split_order_sn = $request->input('split_order_sn', []);

        if(empty($ids)) {
            return $this->error('请选择入仓单');
        }

        if(empty($take_order_no)) {
            return $this->error('请输入提单号');
        }

        if(!$this->validate_sn($take_order_no)){
            return $this->error('提单号格式错误');
        }

//        $find_take_order = TakeOrderModel::where('sn', $take_order_no)->first();
//        if($find_take_order) {
//            return $this->error('提单号已使用');
//        }

        $flight = FlightModel::find($flight_id);
        if(!$flight) {
            return $this->error('航班运力不存在');
        }

        $orders = OrderModel::withCount('split_order_addr')->whereIn('id', $ids)->get();
        if($orders->isEmpty()) {
            return $this->error('入仓单不存在');
        }

//        $sum_volume = $orders->sum('storage_volume') / 1E6;
////        if($flight->surplus_volume < $sum_volume) {
////            return $this->error('航班运力剩余体积不足');
////        }
//
//        $sum_weight = $orders->sum('storage_weight');
////        if($flight->surplus_weight < $sum_weight) {
////            return $this->error('航班运力剩余重量不足');
////        }

        if($orders->count() != count($ids)) {
            return $this->error('入仓单错误');
        }

        $customer_ids = array_unique($orders->pluck('customer_id')->toArray());
        if(count($customer_ids) != 1) {
            return $this->error('请选择同一个客户的入仓单');
        }

        $destination = array_unique($orders->pluck('destination')->toArray());
        if(count($destination) != 1) {
            return $this->error('入仓单目的地不一致');
        }

        $split_order_count = $orders->sum('split_order_addr_count');
        if($split_order_count != count($split_order_sn)) {
            return $this->error('分单号数量错误');
        }

        $goods_attr = array_unique($orders->pluck('goods_attr')->toArray());
        if(count($goods_attr) != 1) {
//            return $this->error('入仓单货物属性不一致');
            $goods_attr = OrderModel::GOODS_ATTR_SPECIAL;
        }else{
            $goods_attr = $goods_attr[0];
        }



        //航线
        $route_id = $flight->items->first()->route_id ?? 0;

        $auth = $request->get('auth');
        DB::beginTransaction();
        try {
            $take_order = TakeOrderModel::where('sn', $take_order_no)->first();

            if(!$take_order) {
                $take_order = new TakeOrderModel();
                $take_order->sn = $take_order_no;
                $take_order->flight_id = $flight->id;
                $take_order->master = $flight->carrier;
                $take_order->goods_attr = $goods_attr;
                $take_order->created_admin_id = $auth->id;
                $take_order->customer_id = $orders->first()->customer_id;
                $take_order->big_pkgs = $orders->sum('big_pkgs');
                $take_order->route_id = $route_id;
                $take_order->destination = $destination[0] ?? '';
                $take_order->save();
            } else {
                if($take_order->customer_id != $orders->first()->customer_id) {
                    throw new AppException('客户不一致');
                }

                $take_order->flight_id = $flight->id;
                $take_order->master = $flight->carrier;
                $take_order->goods_attr = $goods_attr;
                $take_order->created_admin_id = $auth->id;
                $take_order->customer_id = $orders->first()->customer_id;
                $take_order->big_pkgs = $orders->sum('big_pkgs');
                $take_order->route_id = $route_id;
                $take_order->destination = $destination[0] ?? '';
                $take_order->save();
            }

            //应收费用
//            $common_price = CommonPriceModel::first();
//            if(!$common_price) {
//                throw new AppException('未设置公共价格');
//            }

//            //提单费
//            TakeOrderRecModel::create([
//                'take_order_id' => $take_order->id,
//                'currency' => 'CNY',
//                'symbol' => '¥',
//                'type' => TakeOrderRecModel::TYPE_TAKE,
//                'amount' => $common_price->tidan_price,
//                'sys_amount' => $common_price->tidan_price,
//                'is_sys' => 1,
//            ]);

//            //分单费
//            $split_fee = $split_order_count * $common_price->fendan_price;
//            TakeOrderRecModel::create([
//                'take_order_id' => $take_order->id,
//                'currency' => 'CNY',
//                'symbol' => '¥',
//                'type' => TakeOrderRecModel::TYPE_SPLIT,
//                'amount' => $split_fee,
//                'sys_amount' => $split_fee,
//                'is_sys' => 1,
//            ]);

            foreach ($orders as $order) {
                if($order->cargo_status == OrderModel::CARGO_STATUS_NO) {
                    throw new AppException('入仓单未配舱');
                }

                $order->cargo_status = OrderModel::CARGO_STATUS_FILL;
                $order->take_order_id = $take_order->id;
                $order->flight_id = $flight->id;
                $order->save();

                //分单
                $split_orders = $order->split_order_addr;
                foreach ($split_orders as $split_order) {
                    $split_order->sn = $split_order_sn[0] ?? '';
                    unset($split_order_sn[0]);
                    $split_order_sn = array_values($split_order_sn);
                    $split_order->save();
                }
            }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
        return $this->success();
    }

    //自动配舱
    public function auto_cargo(Request $request) {
        $rules = DestinationRuleModel::get();
        foreach($rules as $rule) {
            $flights = FlightModel::where('destination_id', $rule->country_id)->get();
            if($flights->count() == 0) { continue; }

            foreach([$rule->first, $rule->second, $rule->third] as $rt) {
                switch($rt) {
                    case DestinationRuleModel::RULE_PIVOT:
                        foreach($flights as $flight) {
                            $povit = BanModel::whereIn('id', $flight->bans->pluck('ban_id'))->sum('pivot');
                            $povit = min($povit, $flight->surplus_weight);
                            $loaded = $flight->weight - $flight->surplus_weight;
                            while($loaded < $povit) {
                                $order =  OrderModel::where('cargo_status', OrderModel::CARGO_STATUS_NO)
                                    ->where('status', OrderModel::STATUS_STORAGE)
                                    ->where('des_country_id', $rule->country_id)
                                    ->where('storage_weight', '<=', $flight->surplus_weight)
                                    ->where('storage_volume', '<=', $flight->surplus_volume * 10e6)
                                    ->where('flight_id', 0)
                                    ->first();
                                if(!$order) break;

                                $order->cargo_status = OrderModel::CARGO_STATUS_NO_FILL;
                                $order->flight_id = $flight->id;
                                $order->save();

                                $flight->surplus_weight -= $order->storage_weight;
                                $flight->surplus_volume -= $order->storage_volume / 10e6;
                                $flight->save();

                                $loaded += $order->storage_weight;
                            }
                        }
                        break;
                    case DestinationRuleModel::RULE_PRICE:
                        //TODO
                        // foreach($flights as $flight) {

                        // }
                        break;
                    case DestinationRuleModel::RULE_CUSTOMER:
                        foreach($flights as $flight) {
                            $customer_ids = CustomerPreferenceModel::whereIn('route_id', $flight->items->pluck('route_id'))
                                ->pluck('customer_id');
                            while(true) {
                                $order =  OrderModel::where('cargo_status', OrderModel::CARGO_STATUS_NO)
                                    ->where('status', OrderModel::STATUS_STORAGE)
                                    ->where('des_country_id', $rule->country_id)
                                    ->where('storage_weight', '<=', $flight->surplus_weight)
                                    ->where('storage_volume', '<=', $flight->surplus_volume * 10e6)
                                    ->where('flight_id', 0)
                                    ->whereIn('customer_id', $customer_ids)
                                    ->first();
                                if(!$order) break;

                                $order->cargo_status = OrderModel::CARGO_STATUS_NO_FILL;
                                $order->flight_id = $flight->id;
                                $order->save();

                                $flight->surplus_weight -= $order->storage_weight;
                                $flight->surplus_volume -= $order->storage_volume / 10e6;
                                $flight->save();
                            }
                        }
                        break;
                }
            }
        }
        return $this->success();
    }

    //已配舱-撤销
    public function fill_cancel($id) {
        $order = OrderModel::find($id);
        if(!$order) {
            return $this->error('入仓单不存在');
        }

        $take_order = TakeOrderModel::find($order->take_order_id);

        DB::beginTransaction();
        try {
            $order->cargo_status = OrderModel::CARGO_STATUS_NO;
            $order->flight_id = 0;
            $order->take_order_id = 0;
            $order->save();

            $take_order->big_pkgs = $take_order->big_pkgs - $order->big_pkgs;
            $take_order->save();

            DB::commit();
        } catch(\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return $this->success();
    }

    //已填提单号
    public function fill(Request $request) {
        $flight_id = $request->input('flight_id', 0);
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 20);
        $customer_name = $request->input('customer_name', '');
        $customer_id = $request->input('customer_id', '');
        $goods_attr = $request->input('goods_attr', '');
        $airport_id = $request->input('airport_id', 0);
        $clearance_mode = $request->input('clearance_mode', '');
        $customer_type_id = $request->input('customer_type_id', '');
        $is_clearance = $request->input('is_clearance', '');
        $pre_out_date_start = $request->input('pre_out_date_start', '');
        $pre_out_date_end = $request->input('pre_out_date_end', '');
        $destination = $request->input('des_country_id', '');

        //    $query = OrderModel::query()
        //        ->where('cargo_status', OrderModel::CARGO_STATUS_FILL)
        //        ->where('flight_id', $flight_id)
        //        ->with(['customer', 'des_country'])
        //        ->withCount('split_order_addr');

        $query = OrderModel::query()->with(['take_order', 'customer'])
            ->whereHas('customer', function ($query) use ($customer_name){
            if($customer_name){
                $query->where('name', 'like', '%'.$customer_name.'%');
            }

        })
            ->where('cargo_status', OrderModel::CARGO_STATUS_FILL)
            ->where('flight_id', $flight_id)
            ->withCount('split_order_addr');

        if($customer_id){
            $query->where('customer_id', $customer_id);
        }

        if($destination){
            $query->where('destination', $destination);
        }

        if($goods_attr){
            $query->where('goods_attr', $goods_attr);
        }

        if($airport_id){
            $query->where('airport_id', $airport_id);
        }

        if($clearance_mode){
            $query->where('clearance_mode', $clearance_mode);
        }

        if($is_clearance){
            $query->where('is_clearance', $is_clearance);
        }

        if($pre_out_date_start && $pre_out_date_end){
            $query->whereBetween('pre_out_date', [$pre_out_date_start, $pre_out_date_end]);
        }

        $total = $query->count('id');
        $items = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $list = $items->map(function($item) {
            $packages = $item->packages ?? '';
            $packages = DictionaryModel::whereIn('id', explode(',', $packages))
                ->pluck('name');
            return [
                'id' => $item->id,
                'customer_name' => $item->customer->name ?? '',
                'sn' => $item->sn,
                'take_order_sn' => $item->take_order->sn ?? '',
                'status_name' => OrderModel::STATUS_MAPS[$item->status] ?? '',
                'big_pkgs' => $item->big_pkgs,
                'pre_out_date' => $item->pre_out_date,
                'des_country_name' => $item->destination ?? '',
                'goods_attr_name' => OrderModel::GOODS_ATTR_MAPS[$item->goods_attr] ?? '',
                'clearance_mode' => OrderModel::CLEARANCE_MODE_MAPS[$item->clearance_mode] ?? '',
                'is_clearance' => $item->is_clearance,
                'storage_weight' => $item->storage_weight,
                'storage_volume' => round($item->storage_volume, 4),
                'pre_volume_weight' => round($item->bubble_weight, 2),
                'volume_ratio' => round($item->pre_weight != 0 ? ($item->pre_volume * 166.67) / $item->pre_weight : 0, 2),
                'packages_name' => $packages,
                'car_number' => $item->car_number,
            ];
        });

        return $this->success(['list' => $list, 'total' => $total]);
    }

    //未填写提单号入仓单
    public function nofill(Request $request)
    {
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 20);
        $flight_id = $request->input('flight_id', 0);
        $customer_name = $request->input('customer_name', '');
        $customer_id = $request->input('customer_id', '');
        $goods_attr = $request->input('goods_attr', '');
        $des_country_id = $request->input('des_country_id', 0);
        $clearance_mode = $request->input('clearance_mode', '');
        $customer_type_id = $request->input('customer_type_id', '');
        $is_clearance = $request->input('is_clearance', '');
        $pre_out_date_start = $request->input('pre_out_date_start', '');
        $pre_out_date_end = $request->input('pre_out_date_end', '');

        //    $query = OrderModel::query()
        //        ->where('cargo_status', OrderModel::CARGO_STATUS_NO_FILL)
        //        ->where('flight_id', $flight_id)
        //        ->with(['customer', 'des_country'])
        //        ->withCount('split_order_addr');

        $query = OrderModel::query()->whereHas('customer', function ($query) use ($customer_name){
            if($customer_name){
                $query->where('name', 'like', '%'.$customer_name.'%');
            }

        })
            ->where('cargo_status', OrderModel::CARGO_STATUS_NO_FILL)
            ->where('flight_id', $flight_id)
            ->withCount('split_order_addr');

        if($customer_id){
            $query->where('customer_id', $customer_id);
        }

        if($goods_attr){
            $query->where('goods_attr', $goods_attr);
        }

        if($des_country_id){
            $query->where('destination', $des_country_id);
        }

        if($clearance_mode){
            $query->where('clearance_mode', $clearance_mode);
        }

        if($is_clearance){
            $query->where('is_clearance', $is_clearance);
        }

        if($pre_out_date_start && $pre_out_date_end){
            $query->whereBetween('pre_out_date', [$pre_out_date_start, $pre_out_date_end]);
        }

        $total = $query->count('id');
        $items = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $list = $items->map(function($item) {
            $packages = $item->packages ?? '';
            $packages = DictionaryModel::whereIn('id', explode(',', $packages))
                ->pluck('name');
            return [
                'id' => $item->id,
                'customer_name' => $item->customer->name ?? '',
                'sn' => $item->sn,
                'status_name' => OrderModel::STATUS_MAPS[$item->status] ?? '',
                'big_pkgs' => $item->big_pkgs,
                'split_order_count' => $item->split_order_addr_count,
                'pre_out_date' => $item->pre_out_date,
                'des_country_name' => $item->destination ?? '',
                'goods_attr_name' => OrderModel::GOODS_ATTR_MAPS[$item->goods_attr] ?? '',
                'clearance_mode' => OrderModel::CLEARANCE_MODE_MAPS[$item->clearance_mode] ?? '',
                'is_clearance' => $item->is_clearance,
                'storage_weight' => $item->storage_weight,
                'storage_volume' => round($item->storage_volume, 4),
                'pre_volume_weight' => round($item->bubble_weight, 2),
                'volume_ratio' => round($item->pre_weight != 0 ? ($item->pre_volume * 166.67) / $item->pre_weight : 0, 2),
                'packages_name' => $packages,
                'car_number' => $item->car_number,
            ];
        });

        return $this->success(['list' => $list, 'total' => $total]);
    }

    //未填提单号-撤销
    public function nofill_cancel(Request $request, int $id) {
        $order = OrderModel::find($id);
        if(!$order) {
            return $this->error('入仓单不存在');
        }

        DB::beginTransaction();
        try {
            // foreach ($orders as $order) {
                if($order->cargo_status != OrderModel::CARGO_STATUS_NO_FILL) {
                    throw new AppException('入仓单未配舱');
                }

                $order->cargo_status = OrderModel::CARGO_STATUS_NO;
                $order->take_order_id = 0;
                $order->is_auto_cargo = 0;
                $order->flight_id = 0;
                $order->save();
            // }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
        return $this->success();
        
    }

    //已配舱提单号
    public function take_orders(Request $request)
    {
        $flight_id = $request->input('flight_id', 0);
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 20);
        $destination = $request->input('destination', '');

        $query = TakeOrderModel::query()
            ->where('flight_id', $flight_id)
            ->where('cargo_status', TakeOrderModel::CARGO_STATUS_YES)
            // ->has('orders')
            ->with([
                'orders' => function($query) {
                    $query->with(['customer'])->withCount('split_order_addr');
                }
            ])
            ->withCount('orders');

        if($destination){
            $query->where('destination', $destination);
        }

        $total = $query->count('id');
        $items = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $list = $items->map(function($item) {
            $split_order_count = $item->orders->sum('split_order_addr_count');
            $big_pkgs = $item->orders->sum('big_pkgs');
            $pre_volume = $item->orders->sum('pre_volume');
            $storage_weight = $item->orders->sum('storage_weight');

            $order_list = $item->orders->map(function($order) {
                $packages = DictionaryModel::whereIn('id', explode(',', $order->packages))
                    ->pluck('name');
                return [
                    'id' => $order->id,
                    'customer_name' => $order->customer->name ?? '',
                    'sn' => $order->sn,
                    'split_order_count' => $order->split_order_addr_count,
                    'big_pkgs' => $order->big_pkgs,
                    'pre_out_date' => $order->pre_out_date,
                    'des_country_name' => $item->destination ?? '',
                    'goods_attr_name' => OrderModel::GOODS_ATTR_MAPS[$order->goods_attr] ?? '',
                    'pre_weight' => $order->pre_weight,
                    'pre_volume' => $order->pre_volume,
                    'pre_volume_weight' => $order->pre_volume * 166.67,
                    'storage_weight' => $order->storage_weight,
                    'packages_name' => $packages
                ];
            });

            $split_order_sn = [];
            foreach($item->orders as $order) {
                $split_order_sn =  array_merge($split_order_sn, $order->split_order_addr->pluck('sn')->toArray());
            }

            return [
                'id' => $item->id,
                'customer_name' => $item->orders->first()->customer->name ?? '',
                'customer_sn' => $item->orders->first()->customer->sn ?? '',
                'customer_type' => $item->orders->first()->customer->customer_type->name ?? '',
                'sn' => $item->sn,
                'order_count' => $item->orders_count,
                'split_order_count' => $split_order_count,
                'big_pkgs' => $big_pkgs,
                'des_country_name' => $item->orders->first()->airport->country_name ?? '',
                'pre_volume' => $pre_volume,
                'pre_volume_weight' => $pre_volume * 166.67,
                'storage_weight' => $storage_weight,
                'order_list' => $order_list,
                'split_order_sn' => $split_order_sn
            ];
        });

        return $this->success(['list' => $list, 'total' => $total]);
    }

    //编辑提单
    public function update(Request $request, int $id) {
        $take_order = TakeOrderModel::find($id);
        if (!$take_order) {
            return $this->error('提单不存在');
        }

        $ids = $request->input('ids', []);
        $take_order_no = $request->input('take_order_no', '');
        $split_order_sn = $request->input('split_order_sn', []);

        if(empty($ids)) {
            return $this->error('请选择入仓单');
        }

        $orders = OrderModel::withCount('split_order_addr')->whereIn('id', $ids)->get();
        if($orders->isEmpty()) {
            return $this->error('入仓单不存在');
        }

        if($orders->count() != count($ids)) {
            return $this->error('入仓单错误');
        }

        $customer_ids = array_unique($orders->pluck('customer_id')->toArray());
        if(count($customer_ids) != 1) {
            return $this->error('请选择同一个客户的入仓单');
        }

        $airport_ids = array_unique($orders->pluck('airport_id')->toArray());
        if(count($airport_ids) != 1) {
            return $this->error('入仓单目的地不一致');
        }

        $split_order_count = $orders->sum('split_order_addr_count');
        if($split_order_count != count($split_order_sn)) {
            return $this->error('分单号数量错误');
        }

        $e = TakeOrderModel::where('sn', $take_order_no)->where('id', '<>', $id)->first();
        if($e) {
            return $this->error('入仓号已存在');
        }

        DB::beginTransaction();
        try {
            $take_order->sn = $take_order_no;
            $take_order->save();

            $olds_orders = OrderModel::where('take_order_id', $take_order->id)
                ->whereNotIn('id', $ids)->get();
            foreach($olds_orders as $old_order) {
                $old_order->take_order_id = 0;
                if($old_order->is_auto_cargo == 1) {
                    $old_order->cargo_status = OrderModel::CARGO_STATUS_NO_FILL;
                } else {
                    $old_order->cargo_status = OrderModel::CARGO_STATUS_NO;
                }
                $old_order->save();
            }
    
            foreach ($orders as $order) {
                $order->cargo_status = OrderModel::CARGO_STATUS_FILL;
                $order->take_order_id = $take_order->id;
                $order->save();

                //分单
                $split_orders = $order->split_order_addr;
                foreach ($split_orders as $split_order) {
                    $split_order->sn = $split_order_sn[0] ?? '';
                    unset($split_order_sn[0]);
                    $split_order_sn = array_values($split_order_sn);
                    $split_order->save();
                }
            }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
        return $this->success();
        
    }

    //已配舱-撤销
    public function cancel($id) {
        $take_order = TakeOrderModel::find($id);
        if(!$take_order) {
            return $this->error('提单不存在');
        }

        DB::beginTransaction();
        try {
            $orders = OrderModel::where('take_order_id', $take_order->id)->get();
            foreach($orders as $order) {
                if($order->is_auto_cargo == 1) {
                    $order->cargo_status = OrderModel::CARGO_STATUS_NO_FILL;
                } else {
                    $order->cargo_status = OrderModel::CARGO_STATUS_NO;
                    $order->flight_id = 0;
                }
                $order->take_order_id = 0;
                $order->save();
            }
            $take_order->delete();

            DB::commit();
        } catch(\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return $this->success();
    }
    
    public function stid($id) {
        $flight = FlightModel::find($id);
        if(!$flight) {
            return $this->error('航班不存在');
        }

        $route_ids = $flight->items->pluck('route_id');

        $routes = RouteModel::whereIn('id', $route_ids)->pluck('code')->implode(',');

        $airline_flight_ids = $flight->items->pluck('airline_flight_id');
        $airline = BaseFlightModel::whereIn('id', $airline_flight_ids)->pluck('flight_number')->implode(',');

        $take_order_ids = $flight->take_orders->pluck('id');
        $order_count = OrderModel::whereIn('take_order_id', $take_order_ids)->count();

        $big_pkgs = OrderModel::whereIn('take_order_id', $take_order_ids)->sum('big_pkgs');

        $load_volume = OrderModel::whereIn('take_order_id', $take_order_ids)->sum('storage_volume');

        $storage_weight = OrderModel::whereIn('take_order_id', $take_order_ids)->sum('storage_weight');

        return $this->success([
            'routes' => $routes,
            'take_off_time' => $flight->take_off_time,
            'airline' => $airline,
            'take_order_count' => $flight->take_orders->count(),
            'order_count' => $order_count,
            'big_pkgs' => $big_pkgs,
            'volume' =>  $load_volume . '/' . $flight->volume,
            'weight' => $storage_weight . '/' . $flight->weight,
            'status' => $flight->status,
        ]);


    }

    //确认配舱
    public function confirm(Request $request) {
        $ids = $request->input('ids', []);

        if(empty($ids)){
            return $this->error('请选择入仓单');
        }

        $orders = OrderModel::whereIn('id', $ids)->get();
        $take_order_ids = $orders->pluck('take_order_id')->toArray();

        if($orders->isEmpty()) {
            return $this->error('入仓单不存在');
        }


        DB::beginTransaction();
        try {
            foreach ($orders as $order){
                $order->cargo_status = OrderModel::CARGO_STATUS_CONFIRM;
                $order->save();
            }

            TakeOrderModel::whereIn('id', $take_order_ids)->update([
                'cargo_status' => TakeOrderModel::CARGO_STATUS_YES,
            ]);

            DB::commit();
        } catch(\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return $this->success();

    }


    public function import_cargo(Request $request) {
        $auth = $request->get('auth');
        $id = $request->input('id', 0);
        $file = $request->file('file');
        if(!$file) {
            return $this->error('请选择文件');
        }

        $flight = FlightModel::find($id);
        if(!$flight) {
            return $this->error('排货不存在');
        }

        $import = new CargoImport();
        Excel::import($import, $file);

        $res = $import->get_result();

        if(isset($res->error) && $res->error){
            return $this->error(implode(',', $res->error));
        }

        $lines = $res->lines;

        DB::beginTransaction();
        try {
            $sum_volume = $sum_weight = 0;
            foreach ($lines as $line){
                $order_id = $line['order_id'];
                $take_order_sn = $line['take_order_sn'];

                $order = OrderModel::find($order_id);

                $order->cargo_status = OrderModel::CARGO_STATUS_CONFIRM;

                $sum_volume += $order->storage_volume;
                $sum_weight += $order->storage_weight;

                $take_order = TakeOrderModel::where('sn', $take_order_sn)->first();
                if(!$take_order){
                    $take_order = new TakeOrderModel();
                    $take_order->sn = $take_order_sn;
                    $take_order->flight_id = $flight->id;
                    $take_order->master = $flight->carrier;
                    $take_order->goods_attr = $order->goods_attr ?? 1;
                    $take_order->created_admin_id = $auth->id;
                    $take_order->customer_id = $order->customer_id;
                    $take_order->big_pkgs = $order->big_pkgs;
                    $take_order->route_id = $flight->route_id;
                    $take_order->destination = $order->destination;
                    $take_order->cargo_status = TakeOrderModel::CARGO_STATUS_YES;
                    $take_order->save();
                } else {
                    if($take_order->customer_id != $order->customer_id) {
                        throw new AppException('客户不一致');
                    }
                    $take_order->goods_attr = $order->goods_attr ?? 1;
                    $take_order->customer_id = $order->customer_id;
                    $take_order->big_pkgs += $order->big_pkgs;
                    $take_order->destination = $order->destination;
                    $take_order->cargo_status = TakeOrderModel::CARGO_STATUS_YES;
                    $take_order->save();
                }

                $order->take_order_id = $take_order->id;
                $order->save();

            }

            $flight->surplus_volume -= $sum_volume;
            $flight->surplus_weight -= $sum_weight;
            $flight->save();

            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return  $this->success();
    }



    /**
     * 校验提单号格式
     *
     * 校验规则：
     * 1. 提单号横杠后7位-第8位，再除以7，是整数
     * 2. 横杠后第8位数字不能是数字7,8,9
     * 3. 提单号中间不能有空格
     *
     * @param string $billNumber 提单号
     * @return bool 校验结果
     */
    public function validate_sn($billNumber) {
        // 规则3: 检查提单号中间是否有空格
        if (strpos($billNumber, ' ') !== false) {
            return false;
        }

        // 分割提单号
        $parts = explode('-', $billNumber);

        // 检查格式是否正确(必须有且仅有两个部分)
        if (count($parts) !== 2) {
            return false;
        }

        $prefix = $parts[0];
        $suffix = $parts[1];

        // 检查后缀长度是否为8位数字
//        if (strlen($suffix) !== 8 || !is_numeric($suffix)) {
//            return false;
//        }

        // 规则2: 检查第8位数字不能是7,8,9
        $eighthDigit = intval($suffix[7]);
        if (in_array($eighthDigit, [7, 8, 9])) {
            return false;
        }

        // 规则1: 提单号横杠后7位-第8位，再除以7，是整数
        $firstSevenDigits = intval(substr($suffix, 0, 7));
        $lastDigit = $eighthDigit;

        // 计算 (前7位数字 - 第8位数字) / 7 是否为整数
        $result = ($firstSevenDigits - $lastDigit) / 7;

        // 检查结果是否为整数
        if ($result != intval($result)) {
            return false;
        }

        return true;
    }

}
